package com.gxa.eshops.portal.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gxa.eshops.portal.thread.UserThreadLocal;
import com.gxa.eshps.cores.exception.BusinessException;
import com.gxa.eshps.cores.exception.ExceptionCode;
import com.gxa.eshps.cores.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Map;

/**
 * @program: IntelliJ IDEA
 * @description:
 * @author: Mr.Wang
 * @create: 2022-07-07 11:32
 **/
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    RestTemplate restTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, @Nonnull HttpServletResponse response,@Nonnull Object handler) throws Exception {

        //从前端的请求头获取token
        String token = request.getHeader("token");
        //没有token直接拦截并抛出异常
        if (StringUtils.isEmpty(token)){
            throw new BusinessException(ExceptionCode.EMPTY_TOKEN);
        }
        //发起向sso服务器的远程调用
        //url
        String url = "http://localhost:8090/user/checkWithToken";
        //请求头（请求类型）
        HttpHeaders httpHeaders = new HttpHeaders();
        //指定了参数类型
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //请求参数
        MultiValueMap<String,String> params = new LinkedMultiValueMap<>();
        params.add("token",token);
        //请求类型
        //HttpEntity:Spring 封装一个传递http请求的实体类型
        HttpEntity httpEntity = new HttpEntity(params,httpHeaders);

        //通过post方式发送的方法
        Map map = restTemplate.postForObject(url,httpEntity,Map.class);
        //完成通信,获取返回的消息:正常code=1 ,异常code=0 token验证不通过
        assert map != null;
        if (!"1".equals(map.get("code"))){
            throw new BusinessException(ExceptionCode.WRONG_TOKEN);
        }
        //校验通过,给前端返回信息
        Object data = map.get("data");
        ObjectMapper objectMapper = new ObjectMapper();
        String value = objectMapper.writeValueAsString(data);
        //value放入ThreadLocal作用域
        UserThreadLocal.set(value);
        return true;
    }
}
